using Microsoft.Xna.Framework;
//Source http://gamecamp.no/blogs/tutorials/archive/2008/03/16/xna-3dengine-camera-and-game-services-part-3.aspx
namespace whereIsTheDonutGame
{
    public class Camera : GameComponent, ICamera
    {
        private Vector3 _position;
        private Vector3 _lookAt;
        private Matrix _viewMatrix;
        private Matrix _projectionMatrix;

        private IPlayer player;

        public Camera(Game game)
            : base(game)
        {
            player = (IPlayer)Game.Services.GetService(typeof(IPlayer));
        }

        public Vector3 Position
        {
            get { return this._position; }
            set { this._position = value; }
        }
        public Vector3 LookAt
        {
            get { return this._lookAt; }
            set { this._lookAt = value; }
        }
        public Matrix ViewMatrix
        {
            get { return this._viewMatrix; }
        }
        public Matrix ProjectionMatrix
        {
            get { return this._projectionMatrix; }
        }

        public override void Update(GameTime gameTime)
        {
            updatePosition();
            this._viewMatrix = Matrix.CreateLookAt(this._position, this._lookAt, Vector3.Up);
        }

        private void updatePosition()
        {
            // Gets the position of our player from the IPlayer service.
            this._position = player.Position;
            // Updates our cameras lookAt vector. 
            updateLookatVector();
        }

        private void updateLookatVector()
        {
            // Turn the camera in the direction that our hero is facing
            Matrix rotation = Matrix.CreateRotationY(player.Rotation);
  

            // Gets the displacement vector.
            Vector3 transformReference = Vector3.Transform(Vector3.Forward, rotation);

                // Finally changes the lookAt vector. this wants to be right in front of the character.
                // It's very important to change this every time the character moves or rotates.
                // if the lookAt vector isn't directly in front of the character at all times, 
                // it moves out of sync (and kind of funny :D).
            this._lookAt = _position + transformReference;
        }

        public override void Initialize()
        {
            this._projectionMatrix = Matrix.CreatePerspectiveFieldOfView(
                                        MathHelper.ToRadians(40.0f),
                                        this.Game.GraphicsDevice.DisplayMode.AspectRatio,
                                        0.1f,
                                        10000.0f);

            base.Initialize();
        }
    }
}
